//
// Created by 215609 on 2024/8/7.
//

#ifndef TSAVPLAYER_BASEDECODER_H
#define TSAVPLAYER_BASEDECODER_H
extern "C"{
#include "libavformat/avformat.h"
#include "libavcodec/avcodec.h"
#include <libavutil/opt.h>
#include "libswscale/swscale.h"
#include "libswresample/swresample.h"
#include "libavutil/imgutils.h"
#include "libavutil/time.h"
}
#include <LogUtil.h>
#include <thread>
#include "Decoder.h"
using namespace std;
#define MAX_PATH 2048
#define DELAY_THRESHOLD 100
enum DecoderState {
    STATE_UNKNOWN,
    STATE_DECODING,
    STATE_PAUSE,
    STATE_STOP
};

enum DecoderMsg {
    MSG_DECODER_INIT_ERROR,
    MSG_DECODER_READY,
    MSG_DECODER_DONE,
    MSG_REQUEST_RENDER,
    MSG_DECODING_TIME
};
class BaseDecoder :public Decoder{
public:

    virtual void Start();
    virtual void Stop();

    BaseDecoder(){};
    virtual~ BaseDecoder(){};

    virtual void ClearCache();

    virtual void SetMessageCallback(void* context, MessageCallback callback)
    {
        m_MsgContext = context;
        m_MsgCallback = callback;
    }

    AVCodecContext *GetCodecContext() {
        return m_AVCodecContext;
    }

//    virtual void Start();
//
//    virtual void Pause();
//
//    virtual void Seek(int64_t time);
//


protected:

    void * m_MsgContext = nullptr;

    MessageCallback m_MsgCallback = nullptr;

    virtual int Init(const char *path,AVMediaType mediaType);

    virtual void UnInit();

    virtual void OnDecoderReady() = 0;

    virtual void OnDecoderDone() = 0;

    virtual void OnFrameAvailable(AVFrame *frame) = 0;





//
//    virtual void SeekToPosition(float position);
//
//    virtual float GetCurrentPosition();
//
//    virtual float GetDuration();

private:
    int InitFFDecoder();

    void UnInitDecoder();
    //启动解码线程
    void StartDecodingThread();
    //音视频解码循环
    void UpdateTimeStamp();
    //解码一个packet编码数据
    int DecodeOnePacket();
    //音视频解码循环
    void DecodingLoop();
    //音视频同步
    long AVSync();
    //线程函数
    static void DoAVDecoding(BaseDecoder *decoder);

    //封装格式上下文
    AVFormatContext *m_AVFormatContext = nullptr;

    //解码器
    AVCodec         *m_AVCodec = nullptr;
    //解码器上下文
    AVCodecContext  *m_AVCodecContext = nullptr;
    //总时长 ms
    long             m_Duration = 0;

    //编码的数据包
    AVPacket        *m_Packet = nullptr;

    //解码的帧
    AVFrame         *m_Frame = nullptr;
    //数据流索引
    int              m_StreamIndex = -1;
    //文件地址
    char m_Url[MAX_PATH] = {0};


    volatile float      m_SeekPosition = 0;

    volatile bool       m_SeekSuccess = false;
    //解码器状态
    volatile int  m_DecoderState = STATE_UNKNOWN;
    //锁和条件变量
    mutex               m_Mutex;
    condition_variable  m_Cond;
    thread *m_Thread = nullptr;
    //数据流的类型
    AVMediaType m_MediaType = AVMEDIA_TYPE_UNKNOWN;

    //播放的起始时间
    long             m_StartTimeStamp = -1;

    //当前播放时间
    long             m_CurTimeStamp = 0;
};


#endif //TSAVPLAYER_BASEDECODER_H
